﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AudioMonitor.Controls
{
    public partial class VolumeBarControl : Panel
    {
        private float _volume = 0.5f;
        private Image _foreImage;

        public VolumeBarControl()
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor |
                   ControlStyles.OptimizedDoubleBuffer |
                   ControlStyles.AllPaintingInWmPaint |
                   ControlStyles.UserPaint |
                   ControlStyles.ResizeRedraw, true);

            BackColor = Color.Transparent;
            DoubleBuffered = true;
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                if (!DesignMode)
                {
                    cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT
                    cp.ExStyle |= 0x00000002; // WS_EX_COMPOSITED
                }
                return cp;
            }
        }

        public float Volume
        {
            get => _volume;
            set
            {
                _volume = Math.Max(0, Math.Min(value, 1));
                Invalidate();
            }
        }

        public Image ForeImage
        {
            get => _foreImage;
            set
            {
                _foreImage?.Dispose();
                _foreImage = value;
                Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);
            if (Parent != null)
            {
                Parent.ControlAdded += (s, ev) => Invalidate();
                Parent.ControlRemoved += (s, ev) => Invalidate();
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            if (BackColor != Color.Transparent)
            {
                using (var brush = new SolidBrush(BackColor))
                {
                    e.Graphics.FillRectangle(brush, ClientRectangle);
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (Parent != null)
            {
                using (var bmp = new Bitmap(Parent.Width, Parent.Height))
                using (var g = Graphics.FromImage(bmp))
                {
                    var rect = Parent.RectangleToClient(RectangleToScreen(ClientRectangle));
                    g.TranslateTransform(-rect.X, -rect.Y);
                    var args = new PaintEventArgs(g, rect);
                    InvokePaintBackground(Parent, args);
                    InvokePaint(Parent, args);
                    e.Graphics.DrawImage(bmp, 0, 0, rect, GraphicsUnit.Pixel);
                }
            }

            float logVolume = (float)(Math.Log10(1 + 9 * _volume));
            int visibleHeight = (int)(Height * logVolume);

            if (_foreImage != null)
            {
                e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                e.Graphics.SetClip(new Rectangle(0, Height - visibleHeight, Width, visibleHeight));
                e.Graphics.DrawImage(_foreImage, ClientRectangle);
                e.Graphics.ResetClip();
            }
            else
            {
                using (var brush = new LinearGradientBrush(
                    new Point(0, Height - visibleHeight),
                    new Point(0, Height),
                    Color.FromArgb(180, 30, 144, 255),
                    Color.FromArgb(180, 255, 0, 128)))
                {
                    e.Graphics.FillRectangle(brush, 0, Height - visibleHeight, Width, visibleHeight);
                }
            }
        }
    }
}
